package restless.core.managers {
	
	import com.greensock.TweenMax;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.filters.ColorMatrixFilter;
	import flash.geom.Point;
	import flash.geom.Vector3D;
	import flash.geom.Rectangle;
	import restless.core.RLEParallax;
	
	import restless.core.RLEScreen;
	import restless.core.RLECamera;
	import restless.core.interfaces.I2d;
	import restless.core.interfaces.IStage;
	import restless.core.interfaces.IUR;
	import restless.core.gameObjs.RLEBlitMC;
	import restless.core.gameObjs.RLEManagedObj;
	import restless.core.gameObjs.RLEUpdateRenderObj;
	
	/**
	 * 
	 * @author Jordan Laine
	 * 
	 */
	
	public class RLEScreenManager extends RLEManagedObj {
		
		private var tempScreen:RLEScreen;
		private var tempCamera:RLECamera;
		
		private var parallax:RLEParallax;
		private var blitPoint:Vector3D = new Vector3D(0, 0);
		
		private var overlayBitmap:Bitmap;
		private var overlayBitmapData: BitmapData;
		
		private var worldWidth:int;
		private var worldHeight:int;
		
		private var bkgColor:uint;
		
		private var bBlackNWhite:Boolean = false;
		private var blackNWhite:ColorMatrixFilter;
		private var bParallax:Boolean = false;
		
		private var mainScreen:RLEScreen;
		private var vScreenList:Vector.<RLEScreen> = new Vector.<RLEScreen>;
		private var vScreenIDs:Vector.<String> = new Vector.<String>;
		private var vCameraList:Vector.<RLECamera> = new Vector.<RLECamera>;		
		
		public function RLEScreenManager() {
			setRE();
			mouseM = RE.mouseM;
			worldWidth = RE.worldWidth;
			worldHeight = RE.worldHeight;
			bkgColor = RE.bkgColor;
			visible = true;
			setRect(0, 0, RE.displayWidth, RE.displayHeight);
			
			bitmapData = new BitmapData(width, height, true, 0x00000000);
			bitmap = new Bitmap(bitmapData);
			RE.addChild(bitmap);
			
			overlayBitmapData = new BitmapData(width, height, true, 0X00000000);
			overlayBitmap = new Bitmap(overlayBitmapData);
			RE.addChild(overlayBitmap);
			
			tempPoint = new Point();
			mouseM.setScreenList(vScreenList);
			createScreen(0, 0, rect.width, rect.height, false, "main");
			createCamera(0, 0, rect.width, rect.height);
			changeScreenCamera(0, 0);
		}
		
		// vScreenList[0] is the closest to the screen
		public function createScreen(x:int, y:int, width:int, height:int, top:Boolean, id:String):void {
			tempScreen = new RLEScreen(x, y, width, height);
			tempScreen.sID = id;
			if (top) {
				vScreenList.unshift(tempScreen);
				vScreenIDs.unshift(id);
				
			} else {
				vScreenList.push(tempScreen);
				vScreenIDs.push(id);
			}
			if (mainScreen == null) {
				mainScreen = tempScreen;
			}
		}
		
		public function createCamera(startX:Number, startY:Number, cameraWidth:Number, cameraHeight:Number):void {
			tempCamera = new RLECamera(startX, startY, cameraWidth, cameraHeight);
			vCameraList.push(tempCamera);
		}
		
		public function createParallax():void {
			bParallax = true;
			if (parallax == null) {
				parallax = new RLEParallax(mainScreen.getCamera());
				mainScreen.setParallax(parallax);
			}
		}
		
		public function removeParallaxObj(obj:I2d):void {
			parallax.removeObj(obj);
		}
		
		public function addParallaxObj(obj:I2d):void {
			parallax.addObj(obj);
		}
		
		public function changeParallaxObjLayer(obj:I2d, num:int):void {
			parallax.changeObjLayer(obj, num);
		}
		
		public function setParallaxMoveSpeeds(frontX:Number = 0, backX:Number = 0, frontY:Number = 0, backY:Number = 0):void {
			parallax.setMod(frontX, frontY, backX, backY);
		}
		
		public function onCamera(obj:I2d):void {
			i = vCameraList.length - 1;
			for (i; i > -1; i--) {
				tempCamera = vCameraList[i];
				tempCamera.objOnCamera(obj)
			}
		}
		
		public function addBKGingToScreen(obj:I2d, screen:int = -1):void {
			if (screen == -1) {
				tempScreen = mainScreen;
			} else {
				tempScreen = vScreenList[screen];
			}
			
			if (tempScreen != null) {
				tempScreen.addBKGing(obj);
			}
		}
		
		public function removeBKGingFromScreen(obj:I2d, screen:int = -1):void {
			if (screen == -1) {
				tempScreen = mainScreen;
			} else {
				tempScreen = vScreenList[screen];
			}
			
			if (tempScreen != null) {
				tempScreen.removeBKGing(obj);
			}
		}
		
		public function addOverlayingToScreen(obj:I2d, screen:int = -1):void {
			if (screen == -1) {
				tempScreen = mainScreen;
			} else {
				tempScreen = vScreenList[screen];
			}
			
			if (tempScreen != null) {
				tempScreen.addOverlaying(obj);
			}
		}
		
		public function removeOverlayingFromScreen(obj:I2d, screen:int = -1):void {
			if (screen == -1) {
				tempScreen = mainScreen;
			} else {
				tempScreen = vScreenList[screen];
			}
			
			if (tempScreen != null) {
				tempScreen.removeOverlaying(obj);
			}
		}
		
		public function changeScreenCamera(numScreen:int, numCamera:int):void {
			tempScreen = vScreenList[numScreen];
			tempCamera = vCameraList[numCamera];
			
			if (tempScreen != null && tempCamera != null) {
				tempScreen.changeCamera( tempCamera );
			} else {
				throw Error("You dummy, you cant acess a non existant screen and or camera!");
			}	
		}
		
		public function getCameraList():Vector.<RLECamera> {
			return vCameraList;
		}
		
		public function getCamera(num:int):RLECamera {
			return vCameraList[num];
		}
		
		public function getScreenList():Vector.<RLEScreen> {
			return vScreenList;
		}
		
		public function getScreen(id:String):RLEScreen {
			var num:int = vScreenIDs.indexOf(id);
			return vScreenList[num];
		}
		
		override public function update():void {
			
			for (i = 0; i < vCameraList.length; i++) {
				vCameraList[i].update();
			}
			
			for (i = 0; i < vScreenList.length; i++) {
				vScreenList[i].update();
			}
		}
		
		public override function render():void {
			bitmapData.lock();
			bitmapData.fillRect(rect, 0x00000000);
			i = vScreenList.length - 1;
			for (i; i >-1; i--) {
				tempScreen = vScreenList[i];
				tempScreen.render();
				tempRect = tempScreen.rect;
				tempPoint.x = blitPoint.x;
				tempPoint.y = blitPoint.y;
				bitmapData.copyPixels( tempScreen.bitmapData, tempRect, tempPoint, null, null, true );
			}
			bitmapData.unlock();
		}
		
		public function setRenderPoint(x:int, y:int):void {
			blitPoint.x = x;
			blitPoint.y = y;
		}
		
		public function blackAndWhite(bool:Boolean, duration:Number = 30):void {
			if (bool == bBlackNWhite) { return; }
			bBlackNWhite = bool;
			
			if (bBlackNWhite) {
				tween = TweenMax.to(bitmap, duration, { colorMatrixFilter: { colorize:0x000000, amount:0.7, saturation:0.2 } } );
			} else {
				tween = TweenMax.to(bitmap, duration, {colorMatrixFilter:{colorize:0x000000, amount:0, brightness:1, saturation:1}});
			}
		}
		
		public function tweenColor(color:uint, duration:Number):void {
			
		}
		
		public function getID():int {
			return 99999;
		}
		
		public override function dispose():void {
			mouseM = null;
			tempScreen = null;
			tempCamera = null;
			vCameraList = null;
			vScreenList = null;
			super.dispose();
		}
	}
}